﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using EuroManager.Domain.Simulator.Helpers;

namespace EuroManager.Domain.Simulator.Result
{
    public class GameData
    {
        private List<int> timeUpdates = new List<int>();
        private List<int> score1Updates = new List<int>();
        private List<int> score2Updates = new List<int>();
        private List<HighlightData> highlights = new List<HighlightData>();
        private List<PlayerData> players = new List<PlayerData>();
        private Dictionary<int, PlayerData> players1ByNumber = new Dictionary<int, PlayerData>();
        private Dictionary<int, PlayerData> players2ByNumber = new Dictionary<int, PlayerData>();

        public GameData()
        {
            Ball = new BallData();
        }

        public int Score1 { get; set; }

        public int Score2 { get; set; }

        public int FrameCount { get; set; }

        public int Fps { get; set; }

        public int BallFps { get; set; }
        
        public int PlayerFps { get; set; }

        public int[] TimeUpdates
        {
            get { return timeUpdates.ToArray(); }
        }

        public int[] Score1Updates
        {
            get { return score1Updates.ToArray(); }
        }

        public int[] Score2Updates
        {
            get { return score2Updates.ToArray(); }
        }

        public BallData Ball { get; private set; }

        public PlayerData[] Players
        {
            get { return players.ToArray(); }
        }

        public HighlightData[] Highlights
        {
            get { return highlights.ToArray(); }
        }

        public void AddPlayer(GameTeam team, int number)
        {
            Contract.Requires(number > 0);

            var player = new PlayerData(team, number);
            players.Add(player);

            var dictionary = team == GameTeam.Team1 ? players1ByNumber : players2ByNumber;
            dictionary[number] = player;
        }
        
        public void AddPlayerFrame(GameTeam team, int number, float x, float y, float angle)
        {
            Contract.Requires(number > 0);
            Contract.Requires(x.IsRational());
            Contract.Requires(y.IsRational());
            Contract.Requires(angle.IsRational());

            var dictionary = team == GameTeam.Team1 ? players1ByNumber : players2ByNumber;
            PlayerData player = dictionary[number];
            player.AddFrame(x, y, angle);
        }

        public void UpdateTime(int frameIndex)
        {
            Contract.Requires(frameIndex >= 0);

            timeUpdates.Add(frameIndex);
        }

        public void UpdateScore(GameTeam team, int frameIndex)
        {
            Contract.Requires(frameIndex >= 0);

            List<int> list = (team == GameTeam.Team1 ? score1Updates : score2Updates);
            list.Add(frameIndex);
        }

        public void AddHighlight(int startFrame, int endFrame)
        {
            Contract.Requires(startFrame >= 0);
            Contract.Requires(endFrame >= startFrame);

            if (!highlights.Any() || highlights.Last().EndFrame < startFrame)
            {
                highlights.Add(new HighlightData(startFrame, endFrame));
            }
            else
            {
                HighlightData last = highlights.Last();

                if (endFrame > last.EndFrame)
                {
                    last.EndFrame = endFrame;
                }
            }
        }
    }
}
